package com.ruoyi.door.utils.baofu.http;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;


@Getter
@Setter
@ToString
public class HttpSendModel implements Serializable {

	private static final long serialVersionUID = 1L;

	private String url;
	private String charSet;
	private HttpMethod method;
	private List<NameValuePair> httpparms;
	private String contentType;


	/**
	 * 发送参数格式化
	 * @param kvobject
	 * @return
	 * @throws Exception
	 */
	private List<NameValuePair> handleNameValue(Object kvobject) throws Exception
	{
		List<NameValuePair> resultParm = null;
		if(kvobject.getClass().equals(HashMap.class))
		{
			resultParm = HasMapNameValue(kvobject);
		}else if(kvobject.getClass().equals(TreeMap.class)){
			resultParm = HasMapNameValue(kvobject);
		}else{
			resultParm = ObjectNameValue(kvobject);
		}
		return resultParm;
	}

	/***
	 * 处理HashMap
	 * @param kvobject
	 * @return
	 * @throws Exception
	 */
	private List<NameValuePair> HasMapNameValue(Object kvobject)throws Exception
	{
		Map<String,Object> resultMap = (Map<String,Object>) kvobject;
		List<NameValuePair> resultParm = new ArrayList<>();
		if(resultMap.keySet().size()<=0) throw  new Exception("Map not data");
		for(String Key:resultMap.keySet())
		{
			if(!StringUtils.isBlank(Key))
			{
				Object ValueObject =  resultMap.get(Key);
				NameValuePair tmpNVP = getNaveValues(Key,ValueObject);
				if(null != tmpNVP) resultParm.add(tmpNVP);
			}
		}
		return resultParm;
	}


	/**
	 * 处理对象
	 * @param kvobject
	 * @return
	 * @throws Exception
	 */
	private List<NameValuePair> ObjectNameValue(Object kvobject)throws Exception
	{
		Class<?> clazz = kvobject.getClass();
		List<NameValuePair> resultParm = new ArrayList<>();
		Field[] fields = clazz.getDeclaredFields();
		for (Field TempFiled :fields)
		{
			if(!StringUtils.isBlank(TempFiled.getName()))
			{
				String KeyNameStr = TempFiled.getName();
				TempFiled.setAccessible(true);
				Object ValueObject =  TempFiled.get(kvobject);
				NameValuePair tmpNVP = getNaveValues(KeyNameStr,ValueObject);
				if(null != tmpNVP) resultParm.add(tmpNVP);
			}
		}
		return resultParm;
	}


	/**
	 * 处理值的类型
	 * @param KeyNameStr
	 * @param innv
	 * @return
	 */
	private NameValuePair getNaveValues(String KeyNameStr, Object innv)
	{
		NameValuePair tmpNVP = null;
		if(innv == null)
		{
			tmpNVP = new BasicNameValuePair(KeyNameStr,"");
		}else if(StringUtils.isBlank(innv.toString()))
		{
			tmpNVP = new BasicNameValuePair(KeyNameStr,"");
		}
		else if(innv.getClass().equals(String.class))
		{
			tmpNVP = new BasicNameValuePair(KeyNameStr,innv.toString());
		}
		else if(innv.getClass().equals(String.class)){
			tmpNVP = new BasicNameValuePair(KeyNameStr,innv.toString());
		}
		else{
			tmpNVP = new BasicNameValuePair(KeyNameStr,innv.toString());
		}
		return tmpNVP;
	}

	public HttpSendModel() {
		charSet = CharSet.Default;
		method = HttpMethod.getDefault();
		contentType="application/x-www-form-urlencoded";
	}


	public HttpSendModel(String inurl,Object inParms) throws Exception
	{
		charSet = CharSet.Default;
		method = HttpMethod.getDefault();
		contentType="application/x-www-form-urlencoded";

		if(StringUtils.isBlank(inurl)) throw new Exception("Url Error");
		if(inParms == null) throw new Exception("Parms is Null");
		this.url = inurl;
		this.httpparms = handleNameValue(inParms);
	}


	/**
	 * 生成get模式的请求地址
	 * 
	 * @return
	 */
	public String buildGetRequestUrl() {

		String url = this.getUrl();
		String charSet = this.getCharSet();

		String requestUrl = url;
		if (this.httpparms != null && this.httpparms.size() != 0) {
			String appender = URLEncodedUtils.format(this.httpparms, charSet);
			if (url.indexOf("?") == -1) {// 用于url不存在参数的情况
				requestUrl += "?" + appender;
			}else {// 用于url已存在参数的情况
				requestUrl += "&" + appender;
			}
		}
		return requestUrl;
	}


}
